package com.adopapa.nezhacloud.authc.service;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.adopapa.nezhacloud.authc.conf.AuthcConstants;
import com.adopapa.nezhacloud.authc.domain.LoginUser;
import com.adopapa.nezhacloud.authc.domain.ResourceInfo;
import com.adopapa.nezhacloud.authc.domain.ResourcePerm;
import com.adopapa.nezhacloud.authc.domain.RoleInfo;
import com.adopapa.nezhacloud.authc.domain.RolePerm;
import com.adopapa.nezhacloud.authc.domain.UserInfo;
import com.adopapa.nezhacloud.authc.utils.JwtUtils;
import com.adopapa.nezhacloud.common.Tools;
import com.adopapa.nezhacloud.ddd.service.BaseService;
import com.adopapa.nezhacloud.redis.RedisService;

@Service
public class SystemDataService extends BaseService {

//	@Autowired
//	private UserInfoService userInfoService;
//	@Autowired
//	private RoleInfoService roleInfoService;
//	@Autowired
//	private ResourceInfoService resourceInfoService;
	@Autowired
	private RolePermService rolePermService;
	@Autowired
	private ResourcePermService resourcePermService;
	@Autowired
	private RedisService redisService;

	@Transactional
	public void selectRoles(UserInfo userInfo, List<RoleInfo> roleInfos) {

		List<RolePerm> rolePerms = rolePermService.getRolePermByUserInfo(userInfo);
		if (!Tools.empty(rolePerms)) {
			rolePermService.deleteRolePerms(rolePerms);
		}
		rolePerms.clear();
		roleInfos.forEach(role -> {
			RolePerm rolePerm = new RolePerm();
			rolePerm.setRoleInfo(role);
			rolePerm.setUserInfo(userInfo);
			rolePerms.add(rolePerm);
		});

		rolePermService.saveRolePerms(rolePerms);

	}
	@Transactional
	public void selectResources(RoleInfo roleInfo, List<ResourceInfo> resourceInfos) {

		List<ResourcePerm> resourcePerms = resourcePermService.getResourcePermByRoleInfo(roleInfo);
		if (!Tools.empty(resourcePerms)) {
			resourcePermService.deleteResourcePerms(resourcePerms);
		}
		resourcePerms.clear();
		resourceInfos.forEach(resource -> {
			ResourcePerm resourcePerm = new ResourcePerm();
			resourcePerm.setResourceInfo(resource);
			resourcePerm.setRoleInfo(roleInfo);
			resourcePerms.add(resourcePerm);
		});

		resourcePermService.saveResourcePerms(resourcePerms);
	}

	public List<RoleInfo> getRoleInfos(UserInfo userInfo) {
		List<RolePerm> rolePerms = rolePermService.getRolePermByUserInfo(userInfo);
		List<RoleInfo> roleInfos = rolePerms.stream().map(RolePerm::getRoleInfo).collect(Collectors.toList());
		return roleInfos;
	}

	public List<ResourceInfo> getResourceInfos(RoleInfo roleInfo) {
		List<ResourcePerm> resourcePerms = resourcePermService.getResourcePermByRoleInfo(roleInfo);
		List<ResourceInfo> resourceInfos = resourcePerms.stream().map(ResourcePerm::getResourceInfo)
				.collect(Collectors.toList());
		return resourceInfos;
	}

	public List<ResourceInfo> getResourceInfos(List<RoleInfo> roleInfos) {
		List<ResourceInfo> resourceInfos = new LinkedList<>();
		for (RoleInfo roleInfo : roleInfos) {
			resourceInfos.addAll(getResourceInfos(roleInfo));
		}
		return resourceInfos;
	}

	public List<ResourceInfo> getResourceInfos(UserInfo userInfo) {
		List<RolePerm> rolePerms = rolePermService.getRolePermByUserInfo(userInfo);
		if (Tools.empty(rolePerms)) {
			return null;
		}
		List<ResourceInfo> resourceInfos = new LinkedList<>();

		rolePerms.forEach(rolePerm -> {
			List<ResourcePerm> resourcePerms = //
					resourcePermService.getResourcePermByRoleInfo(rolePerm.getRoleInfo());
			if (!Tools.empty(resourcePerms)) {
				resourcePerms.forEach(resourcePerm -> {
					resourceInfos.add(resourcePerm.getResourceInfo());
				});
			}
		});

		return resourceInfos;

	}

	public boolean auth(String token, String accessUrl) {
		String userKey = JwtUtils.getTokenKey(token);
		RedisTemplate<String, Object> redisTemplate = redisService.getRedisTemplate(AuthcConstants.AUTHC_REDIS_DBINDEX);
		LoginUser loginUser = (LoginUser) redisTemplate.opsForValue().get(userKey);
		if (Tools.empty(loginUser)) {
			return false;
		}
//		if (!loginUser.getResources().contains(accessUrl)) {
//			return false;
//		}
		for (String resource : loginUser.getResources()) {
			// xxxxxx/{path}
			if (resource.indexOf("/{") > 0) {
				if (accessUrl.indexOf(resource.substring(0, resource.lastIndexOf("/{"))) >= 0) {
					return true;
				}
			} else {
				if (accessUrl.indexOf(resource) >= 0) {
					return true;
				}
			}
		}
		return false;
	}

}
